package com.xxx.orderservice.controller;

import com.alibaba.fastjson.JSON;
import com.xxx.orderservice.feignClient.UserServiceFeignClient;
import com.xxx.orderservice.pojo.entity.Order;
import com.xxx.orderservice.service.OrderService;
import com.xxx.orderservice.service.impl.MessageProducer;
import com.xxx.util.pojo.User;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import jakarta.annotation.Resource;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;

@RestController
@RequestMapping(value = "/order")
@RefreshScope   // 开启nacos配置自动刷新
public class OrderController {

    @Resource
    private OrderService orderService;
    @Resource
    private UserServiceFeignClient userServiceFeignClient;
    @Resource
    private MessageProducer messageProducer;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private RestTemplate restTemplate;

    // 获取nacos配置
    @Value("${config.info}")
    private String configInfo;

    /**
     * http://localhost:9082/order/index
     */
    @GetMapping(value = "/index")
    public String index (){
        return "this is order-service";
    }

    /**
     * 测试Nacos配置中心
     * http://localhost:9082/order/testNacosConfig
     */
    @GetMapping(value = "/testNacosConfig")
    public String testNacosConfig (){
        return configInfo;
    }

    /**
     * 测试微服务调用
     * http://localhost:9082/order/testNacosDiscovery/11111111111111
     */
    @RequestMapping(value = "/testNacosDiscovery/{str}", method = RequestMethod.GET)
    public String testNacosDiscovery(@PathVariable String str) {
        return restTemplate.getForObject("http://user-service/user/testNacosDiscovery/" + str, String.class);
    }

    /**
     * 测试openfeign
     * http://localhost:9082/order/testOpenFeign?userId=1
     */
    @GetMapping(value = "/testOpenFeign")
    @ResponseBody
    public boolean testOpenFeign (Integer userId){
        User user = new User();
        user.setUuid(UUID.randomUUID().toString());
        user.setUserId(userId);
        user.setState(1);
        user.setMoney(new BigDecimal("100"));
        user.setCreateTime(LocalDateTime.now());
        return userServiceFeignClient.addUser(user);
    }

    /**
     * 测试mysql
     * http://localhost:9082/order/testMySQL?orderNo=123
     */
    @GetMapping(value = "/testMySQL")
    @ResponseBody
    public Order testMySQL (String orderNo){
        return orderService.getByOrderNo(orderNo);
    }

    /**
     * 测试redis
     * http://localhost:9082/order/testSetRedis?orderNo=123
     */
    @GetMapping(value = "/testSetRedis")
    @ResponseBody
    public String testSetRedis (String orderNo){
        Order order = orderService.getByOrderNo(orderNo);
        if(order!=null) {
            stringRedisTemplate.opsForValue().set(orderNo, JSON.toJSONString(order));
            return "success";
        }
        return "fail";
    }
    /**
     * 测试redis
     * http://localhost:9082/order/testGetRedis?orderNo=123
     */
    @GetMapping(value = "/testGetRedis")
    @ResponseBody
    public Order testGetRedis (String orderNo){
        String json = stringRedisTemplate.opsForValue().get(orderNo);
        if(!StringUtils.isEmpty(json)) {
            return JSON.parseObject(json, Order.class);
        }
        return new Order();
    }

    /**
     * 测试seata AT模式
     * http://localhost:9082/order/addOrder1?orderNo=111&userId=1&amount=10
     */
    @GetMapping(value = "/addOrder1")
    @ResponseBody
    @GlobalTransactional   // seata全局事务入口
    public String addOrder1(String orderNo, String userId, String amount){
        // 在本地事务里新增订单
        Order entity = new Order();
        entity.setOrderNo(Integer.parseInt(orderNo));
        entity.setUserId(Integer.parseInt(userId));
        entity.setOrderAmount(new BigDecimal(amount));
        entity.setCreateTime(LocalDateTime.now());
        entity.setUpdateTime(LocalDateTime.now());
        boolean result = orderService.save(entity);
        if(result) {
            // 在另一个微服务里扣减账户余额
            result = userServiceFeignClient.deductMoneyByAT(userId, new BigDecimal(amount));

//            // 模拟全局事务异常
//            int n = 10 / 0;
        }

        if(result) {
            return "success";
        } else {
            return "fail";
        }
    }

    /**
     * 测试seata TCC模式
     * http://localhost:9082/order/addOrder2?orderNo=222&userId=1&amount=20
     */
    @GetMapping(value = "/addOrder2")
    @ResponseBody
    @GlobalTransactional(timeoutMills = 600000)   // seata全局事务入口
    public String addOrder2(String orderNo, String userId, String amount){
        // 在本地事务里新增订单
        Order entity = new Order();
        entity.setOrderNo(Integer.parseInt(orderNo));
        entity.setUserId(Integer.parseInt(userId));
        entity.setOrderAmount(new BigDecimal(amount));
        entity.setCreateTime(LocalDateTime.now());
        entity.setUpdateTime(LocalDateTime.now());
        boolean result = orderService.save(entity);
        if(result) {
            // 在另一个微服务里扣减账户余额
            result = userServiceFeignClient.deductMoneyByTCC(userId, new BigDecimal(amount));
            if(!result) {
                throw new RuntimeException("扣减余额失败");
            }

//            // 模拟全局事务异常
//            int n = 10 / 0;
        }

        if(result) {
            return "success";
        } else {
            return "fail";
        }
    }

    /**
     * 测试rocketmq普通消息
     * http://localhost:9082/order/testRocketmq?msg=abc12345
     */
    @GetMapping(value = "/testRocketmq")
    @ResponseBody
    public String testRocketmq (String msg){
        boolean b = messageProducer.sendMessage(msg);
        if(b) {
            return "send msg 【"+msg+"】 success";
        } else {
            return "send msg 【"+msg+"】fail";
        }
    }

    /**
     * 测试rocketmq延时消息
     * http://localhost:9082/order/sendDelayMessage?msg=abc12345
     */
    @GetMapping(value = "/sendDelayMessage")
    @ResponseBody
    public String sendDelayMessage (String msg){
        String delayMsg = "{'delay msg': '"+msg+"'}";
        boolean b = messageProducer.sendDelayMessage(delayMsg, 3);
        if(b) {
            return "send msg 【"+msg+"】 success";
        } else {
            return "send msg 【"+msg+"】fail";
        }
    }

}
